package com.chinairi.mall.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.chinairi.mall.config.ValidatorImpl;
import com.chinairi.mall.service.modelobject.OCTAForSPMO;
import com.chinairi.mall.controller.viewobject.OCTIForSPVO;
import com.chinairi.mall.dao.*;
import com.chinairi.mall.error.BusinessException;
import com.chinairi.mall.error.EmBusinessError;
import com.chinairi.mall.model.*;
import com.chinairi.mall.service.IOrderCommodityTrackService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chinairi.mall.service.modelobject.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务单号商品绑定追踪节点表 服务实现类
 * </p>
 *
 * @author Webgasd
 * @since 2020-08-30
 */
@Service
public class OrderCommodityTrackServiceImpl extends ServiceImpl<OrderCommodityTrackMapper, OrderCommodityTrack> implements IOrderCommodityTrackService {
    @Autowired
    private OrderCommodityTrackMapper orderCommodityTrackMapper;
    @Autowired
    private OrderCommodityTrackAlarmMapper orderCommodityTrackAlarmMapper;
    @Autowired
    private OrderCommodityTrackInformationYesMapper orderCommodityTrackInformationYesMapper;
    @Autowired
    private TrackConfigMapper trackConfigMapper;
    @Autowired
    private TrackInforConfigMapper trackInforConfigMapper;
    @Autowired
    private EnterpriseNoticeDealConfigMapper enterpriseNoticeDealConfigMapper;
    @Autowired
    private ValidatorImpl validator;

    /**
     * 配置所有的追踪点，预警，报警表   这里需要修改
     *
     * @param stringList 服务编号list
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void config(List<String> stringList) {
        /*
        查询企业处理人和通知人的结果集放入map，便于查询
         */
        QueryWrapper<EnterpriseNoticeDealConfig> wrapper1 = new QueryWrapper<>();
        List<EnterpriseNoticeDealConfig> enterpriseNoticeDealConfigList = enterpriseNoticeDealConfigMapper.selectList(wrapper1);
        HashMap<String, String> noticeIdMap = new HashMap<>(16);
        HashMap<String, String> dealIdMap = new HashMap<>(16);
        for (EnterpriseNoticeDealConfig enterpriseNoticeDealConfig : enterpriseNoticeDealConfigList) {
            noticeIdMap.put(enterpriseNoticeDealConfig.getUciDbid(), enterpriseNoticeDealConfig.getEndcNoticeIds());
            dealIdMap.put(enterpriseNoticeDealConfig.getUciDbid(), enterpriseNoticeDealConfig.getEndcDealIds());
        }
        /*
        查询通知处理信息，放入map。便于查询
         */
        QueryWrapper<TrackInforConfig> wrapper2 = new QueryWrapper<>();
        List<TrackInforConfig> trackInforConfigList = trackInforConfigMapper.selectList(wrapper2);
        HashMap<String, String> inforMap = new HashMap<>(16);
        for (TrackInforConfig trackInforConfig : trackInforConfigList) {
            inforMap.put(trackInforConfig.getTrackNumber(), trackInforConfig.getTrackInformation());
        }
        /*
        循环stringList，将每个服务单号serviceId拿出来，使用serviceId查找视图VIEW_SER_OG_CLASS，获取当前服务单号对应的商品的三个类别，
         */
        if (stringList != null && stringList.size() > 0) {
            List<OrderCommodityTrack> orderCommodityTrackList = new ArrayList<>();
            List<OrderCommodityTrackInformationYes> orderCommodityTrackInformationYesList = new ArrayList<>();
            for (String serviceId : stringList) {
                /*
                由serviceId获取对应商品的三种商品类别
                 */
                ViewServiceOGClassMO viewServiceOgClassMo = orderCommodityTrackMapper.selectByServiceId(serviceId);
                if (viewServiceOgClassMo == null) {
                    break;
                }
                /*
                原需求是一并查出并插入追踪节点表。然后一并传给服务提供商，接收后更新预警的计划时间和报警的执行时间。
                目前的新需求是根据三种类别获取到这个服务下的首个追踪节点，并取得其trackNumber。
                 */
                String trackNumber = trackConfigMapper.selectFirst(viewServiceOgClassMo.getServiceType());
                /*
                如果获取到了首节点，即这个商品类别存在已经配置了的追踪首节点，则将该节点放进追踪点列表，并将该节点的数据传给服务提供商。
                若无首节点，则直接break跳出。
                 */
                if (trackNumber == null || "".equals(trackNumber)) {
                    break;
                }
                /*
                创建追踪实体类，用于插入该首节点。鉴于性能，重写方法，改为批量插入。
                 */
                OrderCommodityTrack orderCommodityTrack = new OrderCommodityTrack();
                /*
                生成uuid给追踪节点用
                 */
                String uuid = UUID.randomUUID().toString().replace("-", "");
                /*
                set值，并插入该节点
                 */
                orderCommodityTrack.setOctId(uuid);
                orderCommodityTrack.setServiceId(serviceId);
                orderCommodityTrack.setTrackNumber(trackNumber);
                /*
                查找报警节点，默认报警只有一个报警配置，即订单确认的时间阈值。
                 */
                OrderCommodityTrackInformationYes orderCommodityTrackInformationYes = orderCommodityTrackInformationYesMapper.selectTrackInformationByNumber(trackNumber);
                if (orderCommodityTrackInformationYes == null) {
                    break;
                }
                orderCommodityTrackInformationYes.setOctiyId(UUID.randomUUID().toString().replace("-", ""));
                orderCommodityTrackInformationYes.setOctId(uuid);
                orderCommodityTrackInformationYes.setOctiyNeed(viewServiceOgClassMo.getServiceTime());
                orderCommodityTrackInformationYes.setOctiyNotice(noticeIdMap.get(viewServiceOgClassMo.getServerCode()) == null ? "" : noticeIdMap.get(viewServiceOgClassMo.getServerCode()));
                orderCommodityTrackInformationYes.setOctiyDeal(dealIdMap.get(viewServiceOgClassMo.getServerCode()) == null ? "" : dealIdMap.get(viewServiceOgClassMo.getServerCode()));
                orderCommodityTrackInformationYes.setOctiyInfor(inforMap.get(trackNumber) == null ? "" : inforMap.get(trackNumber));
                /*
                把两者数据压入list。
                 */
                orderCommodityTrackList.add(orderCommodityTrack);
                orderCommodityTrackInformationYesList.add(orderCommodityTrackInformationYes);
            }
            /*
            判断+批量插入，此处注意要先批量插主表节点表，再插子表报警表，否则主从报错。
             */
            if (orderCommodityTrackList.size() > 0) {
                orderCommodityTrackMapper.batchInsert(orderCommodityTrackList);
            }
            if (orderCommodityTrackInformationYesList.size() > 0) {
                orderCommodityTrackInformationYesMapper.batchInsert(orderCommodityTrackInformationYesList);
            }
        } else {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, "服务编号组为空");
        }
    }

    /*
     * 该注释代码保留，作为追踪报警的配置方法，总有地方用的到。
     *                 List<OrderCommodityTrackAlarm> orderCommodityTrackAlarmList = orderCommodityTrackAlarmMapper.selectTAByNumber(trackNumber);
     *                 if (orderCommodityTrackAlarmList.size() > 0) {
     *                     orderCommodityTrackAlarmMapper.batchInsert(orderCommodityTrackAlarmList.stream().peek((list) -> {
     *                         list.setOctaId(UUID.randomUUID().toString().replace("-", ""));
     *                         list.setOctId(uuid);
     *                         list.setAlarmNotice(noticeIdMap.get(viewServiceOgClassMo.getServerCode()) == null ? "" : noticeIdMap.get(viewServiceOgClassMo.getServerCode()));
     *                         list.setAlarmDeal(dealIdMap.get(viewServiceOgClassMo.getServerCode()) == null ? "" : dealIdMap.get(viewServiceOgClassMo.getServerCode()));
     *                         //这里需要拼接信息
     *                         list.setAlarmInformation(inforMap.get(trackNumber) == null ? "" : inforMap.get(trackNumber));
     *                     }).collect(Collectors.toList()));
     *                 }
     */

    /**
     * 获取对应供应商的服务-节点-商品列表，用于预警，字段包括订单信息、商品信息、节点信息，该接口不能分页，List形式传出,现在貌似不用传出，需要去中台获取。
     *
     * @return List
     */
    @Override
    public List<OCTAForSPMO> getAlarmList(OCTAForSPMO octaForSPMO) {
        return orderCommodityTrackMapper.getAlarmListSP(octaForSPMO);
    }

    /**
     * 获取对应供应商的服务-节点-商品列表，用于追踪和报警，字段包括订单信息、商品信息、节点信息，节点需求信息，该接口不能分页
     *
     * @return List
     */
    @Override
    public List<OCTIForSPVO> getInformationList(OCTIForSPVO octiForSPVO) {
        List<OCTIForSPVO> list = orderCommodityTrackMapper.getInformationlistSP(octiForSPVO);
        return list;
    }
}
